001    /*
002     * $RCSfile: Request.java,v $ 
003     *
004     * Created on August 28, 2003, 13:28 AM
005     *
006     * This file is part of the STAR Scheduler.
007     * Copyright (c) 2002-2003 STAR Collaboration - Brookhaven National Laboratory
008     *
009     * STAR Scheduler is free software; you can redistribute it and/or modify
010     * it under the terms of the GNU General Public License as published by
011     * the Free Software Foundation; either version 2 of the License, or
012     * (at your option) any later version.
013     *
014     * STAR Scheduler is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017     * GNU General Public License for more details.
018     *
019     * You should have received a copy of the GNU General Public License
020     * along with STAR Scheduler; if not, write to the Free Software
021     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
022     */
023    package gov.bnl.star.offline.scheduler;
024    
025    import gov.bnl.star.offline.scheduler.*;
026    import java.net.URL;
027    import java.util.*;
028    import java.util.logging.*;
029    
030    import java.util.logging.Logger;
031    import org.w3c.dom.*;
032    
033    
034    /** Holds all the informations describing a job to be executed by the scheduler.
035     * It contains the machine from which it was dispatched, the command line,
036     * the file required for input and output and the environment variables needed
037     * by the process. It can also handle the information about the processes to be
038     * dispatched in order to execute the job. The scheduler Policy will decide this
039     * information and put it in this class for the Dispatcher to use.
040     *
041     * @author  Gabriele Carcassi & Levente Hajdu
042     * @version $Revision: 1.11 $ $Date: 2004/11/03 18:20:59 $
043     */
044    public class Request implements java.io.Serializable {
045        static private Logger log = Logger.getLogger(Request.class.getName());
046        private String username;
047        private String command;
048        private String name;
049        private String id;
050        private String description;
051        private boolean simulation;
052        private List input = new ArrayList();
053        private List output = new ArrayList();
054        private URL stdin;
055        private URL stdout;
056        private URL stderr;
057        private boolean mail;
058        private boolean hasNoInput = true;
059        private int maxFilesPerProcess = -1;
060        private int minFilesPerProcess = -1;
061        private String jobDescriptionFileName;
062        public static URL discard;
063        private List jobs = new ArrayList();
064        
065        
066        private int maxStorageSpace = -1; //new addition 
067        private int minStorageSpace = -1; //new addition
068        private int minMemory = -1; //new addition
069        private int maxMemory = -1; //new addition
070        
071        /** Holds value of property fileListType. It can be "paths" or "rootd" */
072        private String fileListType = "path";
073        
074        /** sets the base ID for the request*/
075        public void setID(String id){
076            this.id = id; 
077        }
078        
079        /** Returns the base jobs ID*/
080        public String getID(){
081            return id; 
082        }
083        
084        /** Sets the list of jobs that where made from this request*/
085        public void setJobs(List jobs){
086            this.jobs = jobs; 
087        }
088        
089        /** Returns a list of all the job objects of this request*/
090        public List getJobs(){
091            return jobs; 
092        }
093        
094        
095        /** Holds value of property filesPerHour. */
096        private double filesPerHour = Double.POSITIVE_INFINITY;
097        
098        static {
099            try {
100                discard = new URL("file:/dev/null");
101            } catch (Exception e) {
102                // Won't happen
103                discard = null;
104            }
105        }
106        
107        private Document xmlDocument;
108        private List inputOrder;
109        
110        /** Holds value of property nProcesses. */
111        private int nProcesses = -1;
112        
113        public Request(){ //LH
114            
115        }
116        
117        public Request(Document xmlDocument) {
118            this.xmlDocument = xmlDocument;
119        }
120    
121        /** Creates a new JobRequest without title and description.
122         * @param username the username submitting the job
123         * @param command the command line to be executed
124         */
125        public Request(String username, String command) {
126            this.username = username;
127            this.command = command;
128        }
129    
130        /** Creates a new JobRequest with a title and a description.
131         * @param username the username submitting the job
132         * @param command the command line to be executed
133         * @param name a short description of the job
134         * @param description a more detailed description of the job
135         */
136        public Request(String username, String command, String name, String description) {
137            this.username = username;
138            this.command = command;
139            this.name = name;
140            this.description = description;
141        }
142        
143        /** Changes the filename of the orginal request sent to the scheduler.
144         */
145        public void setJobDescriptionFileName(String filename) {
146            this.jobDescriptionFileName = filename;
147        }
148    
149        /** Marks the job request as one with input data defined.
150         */
151        public void setHasInput() {
152            hasNoInput = false;
153        }
154    
155        /** Sets the command line to be executed to the remote machine. This method can be
156         * executed only if the current command is null, otherwise an exception will be
157         * thrown.
158         * @param command the command line to be executed
159         */
160        public void setCommand(String command) {
161            if (this.command == null) {
162                this.command = command;
163            } else {
164                throw new IllegalArgumentException(
165                    "Command line can't be changed once it is set");
166            }
167        }
168    
169        /** Sets the location from which the standard input will be reed.
170         * This function can be called only once for JobDescription, meaning that
171         * once the input is set it cannot be changed. A second call will generate
172         * an IllegalArgumentException.
173         * @param stdin a file containing the input file to be redirected in the standard in
174         */
175        public void setStdIn(URL stdin) {
176            if (this.stdin != null) {
177                throw new IllegalArgumentException(
178                    "The standard input can't be set twice");
179            }
180    
181            this.stdin = stdin;
182        }
183    
184        /** Sets the location in which the standard output will be saved.
185         * This function can be called only once for JobDescription, meaning that
186         * once the output is set it cannot be changed. A second call will generate
187         * an IllegalArgumentException.
188         * @param stdout a file containing the output file where the standard out should be redirected
189         */
190        public void setStdOut(URL stdout) {
191            if (this.stdout != null) {
192                throw new IllegalArgumentException(
193                    "The standard output can't be set twice");
194            }
195    
196            this.stdout = stdout;
197        }
198    
199        /** Sets the location in which the standard error will be saved.
200         * This function can be called only once for JobDescription, meaning that
201         * once the output is set it cannot be changed. A second call will generate
202         * an IllegalArgumentException.
203         * @param stderr a file containing the output file where the standard error should be redirected
204         */
205        public void setStdErr(URL stderr) {
206            if (this.stderr != null) {
207                throw new IllegalArgumentException(
208                    "The standard error can't be set twice");
209            }
210    
211            this.stderr = stderr;
212        }
213    
214        /** Set to true if this job requests is only to be simulated. By simulations we mean
215         * that the scheduler will prepare everything in the same way it would if it was
216         * not a simulation, but it wouldn't execute the final command for the job
217         * submission. For example, it would analize the job, check if it's a valid
218         * request, query the catalog, assign to target, prepare scripts, but don't
219         * dispatch the request.
220         * <p>
221         * This mode is intended to be used by advanced users and developers to check
222         * whether their request was executed correctly. The dispatcher is responsible to
223         * check for this flag, and implement fake dispatching.
224         * @param simulation true if no actual dispatching action is requested
225         */
226        public void setSimulation(boolean simulation) {
227            this.simulation = simulation;
228        }
229    
230        /** Specifies if the queuing system is allowed to send mail to the user.
231         * @param mail true if the user is allowed to recieve mail
232         */
233        public void setMail(boolean mail) {
234            this.mail = mail;
235        }
236    
237        /** Sets the maximum number of files to be dispatched with one process.
238         * @param maxFilesPerProcess the maximum number of files to be dispatched with one process
239         */
240        public void setMaxFilesPerProcess(int maxFilesPerProcess) {
241            this.maxFilesPerProcess = maxFilesPerProcess;
242        }
243    
244        /** Sets the minimum number of files to be dispatched with one process.
245         * <p>
246         */
247        public void setMinFilesPerProcess(int maxFilesPerProcess) {
248            this.minFilesPerProcess = maxFilesPerProcess;
249        }
250      
251        /** Sets the maximum diskspace a job will need */
252        public void setMaxStorageSpace(int maxStorageSpace) {
253            this.maxStorageSpace = maxStorageSpace;
254        }
255        /** Sets the minimum diskspace a job will need */
256        public void setMinStorageSpace(int minStorageSpace) {
257            this.minStorageSpace = minStorageSpace;
258        }
259        /** Sets the maximum memory (ram) a job will need */
260        public void setMaxMemory(int maxMemory) {
261            this.maxMemory = maxMemory;
262        }
263        
264        public int getMaxMemory() {
265            return this.maxMemory;
266        }
267      
268        /** Setter for property fileListType.
269         * @param fileListType New value of property fileListType.
270         *
271         */
272        public void setFileListType(String fileListType) {
273            if (!"rootd".equals(fileListType) && !"paths".equals(fileListType)) {
274                throw new RuntimeException("fileListType can only be 'rootd' or 'paths'");
275            }
276            this.fileListType = fileListType;
277        }
278        
279        /** Setter for property filesPerHour.
280         * @param filesPerHour New value of property filesPerHour.
281         *
282         */
283        public void setFilesPerHour(double filesPerHour) {
284            this.filesPerHour = filesPerHour;
285        }
286        
287        /** Retrieves the filename of the orignal request sent to the scheduler.
288         */
289        public String getJobDescriptionFileName() {
290            return jobDescriptionFileName;
291        }
292        
293        /** Returns the user name under which the job has to run.
294         * @return the username submitting the job
295         */
296        public String getUsername() {
297            return username;
298        }
299    
300        /** Returns true if the job request didn't contain any input.
301         * @return true if not input was specified
302         */
303        public boolean hasNoInput() {
304            return hasNoInput;
305        }
306    
307        /** Returns the command line to be executed on the remote machine.
308         * @return the command line to be executed
309         */
310        public String getCommand() {
311            return command;
312        }
313    
314        /** Returns a title describing the job request.
315         * @return a short description of the job
316         */
317        public String getName() {
318            return this.name;
319        }
320        
321        public void setName(String name) {
322            this.name = name;
323        }
324        
325    
326        /** Returns a description of the job request.
327         * @return a full description of the job
328         */
329        public String getDescription() {
330            return this.description;
331        }
332    
333        /** Returns the location from which the standard input will be read.
334         * @return the file from which to redirect the standard in
335         */
336        public URL getStdIn() {
337            return stdin;
338        }
339    
340        /** Return the location to which the standard output has to be redirected.
341         * @return a file containing the output file where the standard out should be redirected
342         */
343        public URL getStdOut() {
344            return stdout;
345        }
346    
347        /** Return the location to which the standard error has to be redirected.
348         * @return a file containing the output file where the standard error should be redirected
349         */
350        public URL getStdErr() {
351            return stderr;
352        }
353    
354        /** Returns the list of data files that were requested as an input of the
355         * job.
356         * @return the requested input file list
357         */
358        public List getInputList() {
359            return input;
360        }
361    
362        /** Return the list of data files that were requested as an output of the
363         * job.
364         * @return the requested output file list
365         */
366        public List getOutputList() {
367            return output;
368        }
369    
370        /** Returns true if this job requests is only a simulations. By simulations we mean
371         * that the scheduler will prepare everything in the same way it would if it was
372         * not a simulation, but it wouldn't execute the final command for the job
373         * submission. For example, it would analize the job, check if it's a valid
374         * request, query the catalog, assign to target, prepare scripts, but don't
375         * dispatch the request.
376         * <p>
377         * This mode is intended to be used by advanced users and developers to check
378         * whether their request was executed correctly. The dispatcher is responsible to
379         * check for this flag, and implement fake dispatching.
380         * @return true if the scheduler shouldn't dispatch the job
381         */
382        public boolean getSimulation() {
383            return simulation;
384        }
385    
386        /** Returns true if communication by mail from the queuing system is allowed.
387         * @return true if the output, or other messages, can be sent by mail
388         */
389        public boolean getMail() {
390            return mail;
391        }
392    
393        /** Returns how much disk space a job will need to run. */
394        public int getMaxStorageSpace(){
395           return this.maxStorageSpace; 
396        }
397        /** Returns how much disk space a job will need to run. */
398        public int getMinStorageSpace(){
399           return this.minStorageSpace; 
400        }
401        
402        public int getMinMemory() {
403            return minMemory;
404        }
405        
406        /** Sets the resource requirement, for the minimum amount of memory (ram) the job will need to run.
407         * @param minMemory resource requirement, for the minimum amount of memory (ram) the job will need to run.
408         */
409        public void setMinMemory(int minMemory) {
410            this.minMemory = minMemory;
411        }
412        
413        /** Returns the maximum number of files to be dispatched with one process.
414         * @return the maximum number of files to be dispatched with one process
415         */
416        public int getMaxFilesPerProcess() {
417            return this.maxFilesPerProcess;
418        }
419    
420        /** Returns the minimum number of files to be dispatched with one process.
421         * <p>
422         */
423        public int getMinFilesPerProcess() {
424            return this.minFilesPerProcess;
425        }
426    
427        /** Getter for property fileListType.
428         * @return Value of property fileListType.
429         *
430         */
431        public String getFileListType() {
432            return this.fileListType;
433        }
434        
435        /** Getter for property filesPerHour.
436         * @return Value of property filesPerHour.
437         *
438         */
439        public double getFilesPerHour() {
440            return this.filesPerHour;
441        }
442        
443        /** Getter for property inputOrder.
444         * @return Value of property inputOrder.
445         *
446         */
447        public List getInputOrder() {
448            return this.inputOrder;
449        }
450        
451        /** Setter for property inputOrder.
452         * @param inputOrder New value of property inputOrder.
453         *
454         */
455        public void setInputOrder(List inputOrder) {
456            this.inputOrder = inputOrder;
457        }
458    
459        public void prepareInputOrder(String commaSeparated) {
460            inputOrder = new ArrayList();
461            StringTokenizer t = new StringTokenizer(commaSeparated, ",");
462            while (t.hasMoreTokens()) {
463                inputOrder.add(t.nextToken());
464            }
465        }
466        
467        /** Getter for property nProcesses. Returns -1 if nProcess is not set.
468         * @return Value of property nProcesses.
469         *
470         */
471        public int getNProcesses() {
472            return this.nProcesses;
473        }
474        
475        /** Setter for property nProcesses.
476         * @param nProcesses New value of property nProcesses.
477         *
478         */
479        public void setNProcesses(int nProcesses) {
480            if (nProcesses <= 0) throw new IllegalArgumentException("nProcesses must be greater than zero");
481            this.nProcesses = nProcesses;
482        }
483        
484        
485          private String reportText = " ";
486          public void addToReportText(String Text){ reportText = reportText.concat(Text).concat("\n"); }
487          public void SetReportText(String Text){this.reportText = Text;}
488          public String GetReportText(){return reportText;}
489          
490          private int maxWallTime =-1;
491          public void setMaxWallTime(int maxWallTime){this.maxWallTime = maxWallTime;}
492          /**If this value is not set the default is -1*/
493          public int getMaxWallTime(){return maxWallTime;}
494          
495          private int minWallTime =-1;
496          public void setMinWallTime(int minWallTime){this.minWallTime = minWallTime;}
497          /**If this value is not set the default is -1*/
498          public int getMinWallTime(){return minWallTime;}
499        
500    }